﻿using Common;
using Common.CustomException;
using NUnit.Framework;
using SpecFlowTfsLinker.Entities;
using SpecFlowTfsLinker.Test.Common;
using SpecFlowTfsLinker.Test.Resources;

namespace SpecFlowTfsLinker.Test.Builder
{
    [TestFixture]
    public class TestCaseBuilderTest : TestInitialization
    {
        private static TestCase.BuilderTestCase PartialTestCase
        {
            get { return UserStoryResources.Bowling.PartialTestCase; }
        }

        [Test]
        public void CanBuildCompleteTestCase()
        {
            var tc = PartialTestCase.Build();
            Assert.That(tc, Is.Not.Null);
            Assert.That(tc.Name, Is.Not.Null.Or.Empty);
            Assert.That(tc.Given.Count, Is.EqualTo(1));
            Assert.That(tc.When.Count, Is.EqualTo(1));
            Assert.That(tc.Then.Count, Is.EqualTo(1));
        }

        [Test]
        public void CanAddMultipleGivenStatementToTestCase()
        {
            var tc = PartialTestCase
                .Given(TestCaseResources.GutterGame.Given.BaseStatement)
                .Build();

            Assert.That(tc.Given.Count, Is.EqualTo(2));
        }

        [Test]
        public void CanAddMultipleThenStatementToTestCase()
        {
            var tc = PartialTestCase
                .Then(TestCaseResources.GutterGame.Then.BaseStatement)
                .Build();

            Assert.That(tc.Then.Count, Is.EqualTo(2));
        }

        [Test]
        public void CanAddMultipleWhenStatementToTestCase()
        {
            var tc = PartialTestCase
                .When(TestCaseResources.GutterGame.When.BaseStatement)
                .Build();

            Assert.That(tc.When.Count, Is.EqualTo(2));
        }

        [Test]
        public void CanAddStatementsWithQuotedParameter()
        {
            var tc = TestCase.Builder
                .Name(TestCaseResources.GutterGame.Name)
                .Given(TestCaseResources.Addition.Given.BaseStatement)
                .When(TestCaseResources.Addition.When.BaseStatement)
                .Then(TestCaseResources.Addition.Then.BaseStatement)
                .Build();

            Assert.IsNotNull(tc);
            Assert.IsTrue(tc.Given.Count == 1);
            Assert.IsTrue(tc.When.Count == 1);
            Assert.IsTrue(tc.Then.Count == 1);
        }

        [Test]
        public void CanFailedTestCaseCreationWhithoutGiven()
        {
            Assert.Throws(Is.TypeOf(typeof (TestCaseException)).And.Message.EqualTo(Resource.TEST_CASE_BUILD_G_W_T),
                          () => TestCase.Builder
                                    .Name(TestCaseResources.GutterGame.Name)
                                    .Then(TestCaseResources.GutterGame.Then.BaseStatement)
                                    .When(TestCaseResources.GutterGame.When.BaseStatement)
                                    .Build());
        }

        [Test]
        public void CanFailedTestCaseCreationWhithoutName()
        {
            Assert.Throws(
                Is.TypeOf(typeof (TestCaseException)).And.Message.EqualTo(Resource.TEST_CASE_BUILD_WITHOUT_NAME),
                () => TestCase.Builder
                          .Given(TestCaseResources.GutterGame.Given.BaseStatement)
                          .When(TestCaseResources.GutterGame.When.BaseStatement)
                          .Then(TestCaseResources.GutterGame.Then.BaseStatement)
                          .Build());
        }

        [Test]
        public void CanFailedTestCaseCreationWhithoutThen()
        {
            Assert.Throws(Is.TypeOf(typeof (TestCaseException)).And.Message.EqualTo(Resource.TEST_CASE_BUILD_G_W_T),
                          () => TestCase.Builder
                                    .Name(TestCaseResources.GutterGame.Name)
                                    .Given(TestCaseResources.GutterGame.Given.BaseStatement)
                                    .When(TestCaseResources.GutterGame.When.BaseStatement)
                                    .Build());
        }

        [Test]
        public void CanFailedTestCaseCreationWhithoutWhen()
        {
            Assert.Throws(Is.TypeOf(typeof (TestCaseException)).And.Message.EqualTo(Resource.TEST_CASE_BUILD_G_W_T),
                          () => TestCase.Builder
                                    .Name(TestCaseResources.GutterGame.Name)
                                    .Then(TestCaseResources.GutterGame.Then.BaseStatement)
                                    .Given(TestCaseResources.GutterGame.Given.BaseStatement)
                                    .Build());
        }

        [Test]
        public void CanFailedWhenThereIsNoStatement()
        {
            Assert.Throws(Is.TypeOf(typeof (TestCaseException)).And.Message.EqualTo(Resource.TEST_CASE_BUILD_G_W_T),
                          () => TestCase.Builder.Name(TestCaseResources.GutterGame.Name).Build());
        }
    }
}